#include <vector>
#include <iostream>
#include <string.h>
#include <cassert>

#include "myvector.h"

class A
{
public:
    A():m_i(0)
    {
        std::cout << "A()" << std::endl;
    }

    explicit A(int i):m_i(i)
    {
        std::cout << "A(int i)" << std::endl;
    }

    A(const A& other):m_i(other.m_i)
    {
        std::cout << "A(const A& other)" << std::endl;
    }

    A(A&& other):m_i(other.m_i)
    {
        std::cout << "A(A&& other)" << std::endl;
        other.m_i = 0;
    }

    A& operator=(const A& other)
    {
        std::cout << "A& operator=(const A& other)" << std::endl;
        if(this == &other)
        {
            return *this;
        }
        m_i = other.m_i;
        return *this;
    }

    A& operator=(A&& other)
    {
        std::cout << "A& operator=(A&& other)" << std::endl;
        if(this == &other)
        {
            return *this;
        }
        m_i = other.m_i;
        other.m_i = 0;
        return *this;
    }

    ~A()
    {
        std::cout << "~A()" << std::endl;
    }

private:
    int m_i;
};

// 测试默认构造和基本属性
void test_default_construction() {
    myvector<int> vec;
    
    assert(vec.empty() == true);
    assert(vec.size() == 0);
    assert(vec.capacity() == 0);
    
    std::cout << "test_default_construction passed\n";
}

// 测试push_back和边界访问
void test_push_back_and_access() {
    myvector<int> vec;
    
    // 测试空容器访问（应该抛出异常或断言失败）
    bool caught = false;
    try {
        vec[0];
    } catch (...) {
        caught = true;
    }
    assert(caught == true);
    
    // 测试单元素
    vec.push_back(10);
    assert(vec.size() == 1);
    assert(vec.capacity() >= 1);
    assert(vec[0] == 10);
    
    // 测试多个元素
    for (int i = 1; i <= 100; ++i) {
        vec.push_back(i);
    }
    assert(vec.size() == 101);
    assert(vec[100] == 100);
    
    // 测试边界访问at方法
    caught = false;
    try {
        vec[101];
    } catch (const std::out_of_range&) {
        caught = true;
    }
    assert(caught == true);
    
    std::cout << "test_push_back_and_access passed\n";
}

// 测试reserve和resize
void test_reserve_and_resize() {
    myvector<std::string> vec;
    
    // 测试reserve扩大容量
    vec.reserve(10);
    assert(vec.capacity() >= 10);
    assert(vec.size() == 0);
    
    // 测试reserve缩小容量（应该不生效）
    vec.reserve(5);
    assert(vec.capacity() >= 10);
    
    std::cout << "test_reserve_and_resize passed\n";
}

// 测试pop_back
void test_pop_back() {
    myvector<double> vec;
    
    // 测试空容器pop_back（应该安全或抛出异常）
    bool caught = false;
    try {
        vec.pop_back();
    } catch (...) {
        caught = true;
    }
    assert(caught == true || vec.size() == 0);
    
    // 填充元素后测试
    vec.push_back(1.1);
    vec.push_back(2.2);
    vec.push_back(3.3);
    
    vec.pop_back();
    assert(vec.size() == 2);
    assert(vec[1] == 2.2);
    
    vec.pop_back();
    vec.pop_back();
    assert(vec.empty() == true);
    
    std::cout << "test_pop_back passed\n";
}

// 测试拷贝构造和赋值
void test_copy_operations() {
    myvector<int> vec;
    for (int i = 0; i < 5; ++i) {
        vec.push_back(i);
    }
    
    // 测试拷贝构造
    myvector<int> vec2(vec);
    assert(vec2.size() == vec.size());
    assert(vec2.capacity() >= vec2.size());
    for (size_t i = 0; i < vec.size(); ++i) {
        assert(vec2[i] == vec[i]);
    }
    
    // 测试拷贝赋值
    myvector<int> vec3;
    vec3 = vec;
    assert(vec3.size() == vec.size());
    for (size_t i = 0; i < vec.size(); ++i) {
        assert(vec3[i] == vec[i]);
    }
    
    // 测试自赋值
    vec3 = vec3;
    assert(vec3.size() == vec.size());
    
    std::cout << "test_copy_operations passed\n";
}

// 测试移动构造和赋值
void test_move_operations() {
    myvector<std::string> vec;
    vec.push_back("hello");
    vec.push_back("world");
    size_t old_cap = vec.capacity();
    
    // 测试移动构造
    myvector<std::string> vec2(std::move(vec));
    assert(vec.empty() == true); // 原容器应该为空
    assert(vec2.size() == 2);
    assert(vec2[0] == "hello" && vec2[1] == "world");
    assert(vec2.capacity() == old_cap);
    
    // 测试移动赋值
    myvector<std::string> vec3;
    vec3 = std::move(vec2);
    assert(vec2.empty() == true);
    assert(vec3.size() == 2);
    assert(vec3[0] == "hello" && vec3[1] == "world");
    
    std::cout << "test_move_operations passed\n";
}

void test_swap_operation() {
    myvector<int> vec1;
    vec1.push_back(1);
    vec1.push_back(2);
    vec1.push_back(3);

    myvector<int> vec2;
    vec2.push_back(4);
    vec2.push_back(5);
    vec2.push_back(6);

    vec1.swap(vec2);

    assert(vec1.size() == vec2.size());
    assert(vec2.size() == 3);
    assert(vec1[0] == 4 && vec1[1] == 5 && vec1[2] == 6);
    assert(vec2[0] == 1 && vec2[1] == 2 && vec2[2] == 3);

    std::cout << "test_swap_operation passed\n";
}

void test_clear_operation() {
    myvector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);

    vec.clear();

    assert(vec.size() == 0);
    assert(vec.capacity() >= 3);

    std::cout << "test_clear_operation passed\n";
}

// 测试emplace操作（如果实现了）
template<typename T>
void test_emplace_operations(myvector<T>& vec) {
    // 仅当实现了emplace_back才测试
    vec.emplace_back(10, 'a'); // 假设T是std::string
    assert(vec[vec.size() - 1] == "aaaaaaaaaa");
    
    std::cout << "test_emplace_operations passed\n";
}

int main()
{
    test_default_construction();
    test_push_back_and_access();
    test_reserve_and_resize();
    test_pop_back();
    test_copy_operations();
    test_move_operations();
    test_swap_operation();
    test_clear_operation();

    myvector<std::string> vec;
    test_emplace_operations(vec);

    return 0;
}